package org.demo.five;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * 
 * @author  
 * @date    2010-10-26
 * @file    org.demo.five.Race.java
 */
public class Race {

	/**
	 * @param args
	 * @throws InterruptedException 
	 */
	public static void main(String[] args) throws InterruptedException {
		System.out.println("Prepping...");
		Race race = new Race("A","B","C");
		race.run();
	}
	
	private Random rand = new Random();
	private int distance = rand.nextInt(100);
	private List<String> horses = new ArrayList<String>();
	private List<String> places = Collections.synchronizedList(new ArrayList<String>());
	private final CountDownLatch start;
	private final CountDownLatch finish;
	
	public Race(String... names){
		horses.addAll(Arrays.asList(names));
		start = new CountDownLatch(1);
		finish = new CountDownLatch(horses.size());
	}
	
	public void run() throws InterruptedException{
		System.out.println("Add the horses are stepping up to the gate.");
		for (final String h : horses){
			new Thread(new Runnable(){
				@Override
				public void run() {
					try {
						System.out.println(h + " stepping up to the gate.");
						start.await();
						int traveled = 0;
						while (traveled < distance){
							traveled += rand.nextInt(15);
							System.out.println(h + " advanced to " + traveled + ".");
							Thread.sleep(TimeUnit.SECONDS.toMillis(rand.nextInt(3)));
						}
						System.out.println(h + " crossed the finish.");
						places.add(h);
						finish.countDown();
					} catch(Exception e){
						e.printStackTrace();
					}
				}
			}).start();
		}
		System.out.println("Add... they're off.");
		start.countDown();
		finish.await();
		// 
		System.out.println("And we have our winners.");
		System.out.println(places.get(0) + " took the gold.");
		System.out.println(places.get(1) + " took the silver.");
		System.out.println(places.get(2) + " took the bronze.");
	}
}
